#include <iostream>
#include <chrono>
#include <thread>
#include "../common/net.hpp"
#include "../common/dispatcher.hpp"
#include "../client/requestor.hpp"
#include "../client/rpc_caller.hpp"

void callback(const Json::Value &result )
{
    ILOG("callback result : %d" ,result.asInt());
}

int main()
{
    auto requestor = std::make_shared<RPC_project::client::Requestor>();
    auto rpc_caller = std::make_shared<RPC_project::client::RpcCaller>(requestor);

    // 创建dis以及注册对服务端返回的response的处理函数
    auto dispather = std::make_shared<RPC_project::Dispather>();
    auto rpc_response_cb = std::bind(&RPC_project::client::Requestor::onResponse, requestor.get(), std::placeholders::_1, std::placeholders::_2);
    dispather->RegisterHandler<RPC_project::BaseMessage>(RPC_project::MType::RSP_RPC, rpc_response_cb);
    // dispather->RegisterHandler<RPC_project::TopicResponse>(RPC_project::MType::RSP_TOPIC, onTopicResponse);

    auto client = RPC_project::ClientFactory::create("127.0.0.1", 8080);
    auto message_cb = std::bind(&RPC_project::Dispather::onMessage, dispather.get(), std::placeholders::_1, std::placeholders::_2);
    client->SetMessageCallback(message_cb);
    client->Connect();

    auto conn = client->Connection();
    // //同步发送
    // Json::Value params , result;
    // params["num1"]=11;
    // params["num2"]=11;
    // bool ret = rpc_caller->call(conn ,"Add" ,params,result);//同步发送
    // if(ret != false)
    // {
    //     std::cout<<"result:"<<result.asInt()<<std::endl;
    // }

    // // 异步发送
    // Json::Value params1, result1;
    // std::future<Json::Value> res_future;
    // params1["num1"] =22;
    // params1["num2"] =55;
    // bool ret1 = rpc_caller->call(conn, "Add", params1, res_future); 
    // if (ret1 != false)
    // {

    //     result1 = res_future.get(); // 可能抛出异常
    //     ILOG("result: %d" ,result1.asInt() );
    //     // 处理结果
    // }

    //异步发送
    Json::Value params1, result1;
    RPC_project::client::RpcCaller::JsonAsyncResponce res_future;
    params1["num1"] =55;
    params1["num2"] =33 ;
    bool ret1 = rpc_caller->call(conn, "Add", params1, callback); // 同步发送
    DLOG("---------------------------------\n");
    std::this_thread::sleep_for(std::chrono::seconds(1));

    client->Shutdown();
    return 0;
}

// //version_1
// // void onRpcResponse(const RPC_project::BaseConnection::ptr & conn, RPC_project::BaseMessage::ptr & msg)
// // {
// //     //BaseMessage没有向外提供参数的接口 eg:RpcResponse特有的成员函数,还需要
// //     //RPC_project::RpcResponse::ptr rpc_ptr = std::dynamic_pointer_cast<RPC_project::RpcResponse>(msg);用户使用成本高
// //
// //     std::cout<<"客户端接受到了Rpc响应"<<std::endl;
// //     //只进行打印一下
// //     std::string body = rpc_ptr->Serialize();
// //     std::cout<<body<<std::endl;

// // void onTopicResponse(const RPC_project::BaseConnection::ptr & conn, RPC_project::BaseMessage::ptr & msg)
// // {
// //     std::cout<<"客户端接受到了Topic响应"<<std::endl;
// //     //只进行打印一下
// //     std::string body = msg->Serialize();
// //     std::cout<<body<<std::endl;
// // }

// //version_2
// //每个消息的处理函数类型都不同了(RpcResponse 与TopicResponse不同),无法注册, 只能将Dispather::RegisterHandler设置为模版函数
// //但是Dispather中的哈希表无法存储不同类型的数据, 制订了同一类型的类Callback
// void onRpcResponse(const RPC_project::BaseConnection::ptr & conn, RPC_project::RpcResponse::ptr & msg)
// {
//     std::cout<<"客户端接受到了Rpc响应"<<std::endl;
//     //只进行打印一下
//     std::string body = msg->Serialize();
//     std::cout<<body<<std::endl;

// }
// void onTopicResponse(const RPC_project::BaseConnection::ptr & conn, RPC_project::TopicResponse::ptr & msg)
// {
//     std::cout<<"客户端接受到了Topic响应"<<std::endl;
//     //只进行打印一下
//     std::string body = msg->Serialize();
//     std::cout<<body<<std::endl;

// }

// int main()
// {
//     //创建dis以及注册
//     auto dispather = std::make_shared <RPC_project::Dispather>();
//     dispather->RegisterHandler<RPC_project::RpcResponse>(RPC_project::MType::RSP_RPC, onRpcResponse);
//     dispather->RegisterHandler<RPC_project::TopicResponse>(RPC_project::MType::RSP_TOPIC, onTopicResponse);

//     auto client = RPC_project::ClientFactory::create("127.0.0.1" , 8080);
//     auto message_cb =std::bind(&RPC_project::Dispather::onMessage ,dispather.get() , std::placeholders::_1 ,std::placeholders::_2);
//     client->SetMessageCallback(message_cb);
//     client->Connect();

//     RPC_project::BaseMessage::ptr base_ptr1 = RPC_project::MessageFactory::Create(RPC_project::MType::REQ_RPC);
//     RPC_project::RpcRequest::ptr rpc_ptr = std::dynamic_pointer_cast<RPC_project::RpcRequest>(base_ptr1);
//     rpc_ptr->SetMyType(RPC_project::MType::REQ_RPC);
//     rpc_ptr->Setid("111111");
//     rpc_ptr->SetMethod("Add");
//     Json::Value prams;
//     prams["nums1"] =66;
//     prams["nums2"] =22;
//     rpc_ptr->SetParams(prams);
//     std::cout<<"发送消息"<<std::endl;
//     client->Send(rpc_ptr);

//     RPC_project::BaseMessage::ptr base_ptr2 = RPC_project::MessageFactory::Create(RPC_project::MType::REQ_TOPIC);
//     RPC_project::TopicRequest::ptr topic_ptr = std::dynamic_pointer_cast<RPC_project::TopicRequest>(base_ptr2);
//     topic_ptr->Setid("222222");
//     topic_ptr->SetMyType(RPC_project::MType::REQ_TOPIC);
//     topic_ptr->SetTopickKey("news");
//     topic_ptr->SetOpType(RPC_project::TopicOptype::TOPIC_CREATE);
//     client->Send(topic_ptr);

//     sleep(5);
//     client->Shutdown();
//     return 0;
// }